package org.setaria.container
{
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;
	
	import mx.events.CloseEvent;
	import mx.managers.CursorManager;
	import mx.managers.SystemManager;
	
	import org.setaria.event.ResizeSetariaEvent;
	
	import spark.components.BorderContainer;
	import spark.components.Button;
	import spark.components.Group;
	import spark.components.Label;
	
	[Event(name="close", type="mx.events.CloseEvent")]
	[Event(name="restore", type="org.monster.simple.event.ResizeSimpleEvent")]
	[Event(name="maximize", type="org.monster.simple.event.ResizeSimpleEvent")]
	[Event(name="minimize", type="org.monster.simple.event.ResizeSimpleEvent")]
	
	[Style(name="titleBackgroundColor", type="String",format="Color", inherit="no")]
	[Style(name="titleBackgroundAlpha", type="Number", inherit="no")]
	
	public class SetariaTitleModule extends SetariaModule
	{
		
		public static const STATE_NORMAL:String = "normal";
		public static const STATE_MAXIMIZE:String = "maximize";
		public static const STATE_MINIMIZE:String = "minimize";
		
		[Embed(source="/org/setaria/assets/container/resizeCursorH.gif")]
		private static var DEFAULT_RESIZE_CURSOR_HORIZONTAL:Class;
		
		[Embed(source="/org/setaria/assets/container/resizeCursorTLBR.gif")]
		private static var DEFAULT_RESIZE_CURSOR_TL_BR:Class;
		
		[Embed(source="/org/setaria/assets/container/resizeCursorTRBL.gif")]
		private static var DEFAULT_RESIZE_CURSOR_TR_BL:Class;
		
		[Embed(source="/org/setaria/assets/container/resizeCursorV.gif")]
		private static var DEFAULT_RESIZE_CURSOR_VERTICAL:Class;
		
		public function SetariaTitleModule()
		{
			super();
		}
		
		//窗口原大小
		private var normalWidth:int,normalHeight:int;
		//窗口原位置
		private var normalX:Number,normalY:Number;
		private var dragAmountX:Number;
		
		private var dragAmountY:Number;
		
		private var dragMaxX:Number;
		
		private var dragMaxY:Number;
		
		private var dragStartMouseX:Number;
		
		private var dragStartMouseY:Number;
		
		
		/**控制标题栏显示*/
		private var _showTitle:Boolean = true;
		
		private var _maximizable:Boolean=true;
		
		private var _minimizable:Boolean=true;
		
		private var _resizable:Boolean=true;
		
		private var _close:Boolean = true;
		
		private var _dragable:Boolean=true;
		
		//窗口大小状态
		public var sizeState:String = SetariaTitleWindow.STATE_NORMAL;
		
		private var currentResizeHandle:Button;
		private var savedWindowRect:Rectangle;
		
		[SkinPart(required="false")]
		public var titleGroup:Group;
		[SkinPart(required="false")]
		public var titleLable:Label;
		[SkinPart(required="false")]
		public var closeButton:Button;//
		[SkinPart(required="false")]
		public var restoreButton:Button;//
		[SkinPart(required="false")]
		public var maximizeButton:Button;//
		[SkinPart(required="false")]
		public var minimizeButton:Button;//
		
		[SkinPart(required="false")]
		public var bottomLeftButton:Button;//
		[SkinPart(required="false")]
		public var bottomButton:Button;//
		[SkinPart(required="false")]
		public var bottomRightButton:Button;//
		[SkinPart(required="false")]
		public var leftButton:Button;//
		[SkinPart(required="false")]
		public var rightButton:Button;//
		[SkinPart(required="false")]
		public var topButton:Button;//
		[SkinPart(required="false")]
		public var topLeftButton:Button;//
		[SkinPart(required="false")]
		public var topRightButton:Button;//
		
		
		/**
		 *  @private
		 */
		override protected function partAdded(partName:String, instance:Object) : void
		{
			super.partAdded(partName, instance);
			if(instance == titleGroup)
			{
				titleGroup.focusEnabled = false;
				if(!showTitleGroup){
					titleGroup.visible = false;
					titleGroup.includeInLayout = false;
				}else{
					if(dragable)
					{
						titleGroup.addEventListener(MouseEvent.MOUSE_DOWN, dragStart);
						titleGroup.addEventListener(MouseEvent.MOUSE_UP, dragStop);
					}
					if(showMaximizButton)
					{
						titleGroup.addEventListener(MouseEvent.DOUBLE_CLICK, titleDoubleClick);
					}
				}
			}
			else if(instance == titleLable)
			{
				titleLable.focusEnabled = false;
				titleLable.text = this.title;
			}
			else if (instance == closeButton)
			{
				if(showCloseButton){
					closeButton.focusEnabled = false;
					closeButton.addEventListener(MouseEvent.CLICK, closeButton_clickHandler);   
				}else{
					closeButton.visible = false;
					closeButton.enabled = false;
				}
			}
			else if (instance == minimizeButton)
			{
				if(showMinimizButton){
					minimizeButton.focusEnabled = false;
					minimizeButton.addEventListener(MouseEvent.CLICK, minimizeButton_clickHandler);   
				}else{
					minimizeButton.visible = false;
					minimizeButton.enabled = false;
					
				}
			}
			else if (instance == restoreButton)
			{
				restoreButton.visible = false;
				restoreButton.enabled = false;
				if(showMaximizButton){
					restoreButton.focusEnabled = false;
					restoreButton.addEventListener(MouseEvent.CLICK, restoreButton_clickHandler);   
				}
			}
			else if (instance == maximizeButton)
			{
				if(showMaximizButton){
					maximizeButton.focusEnabled = false;
					maximizeButton.addEventListener(MouseEvent.CLICK, maximizeButton_clickHandler);   
				}else{
					maximizeButton.visible = false;
					maximizeButton.enabled = false;
				}
			}
			else if (instance == topButton)
			{
				if(resizeEnabled)
				{
					topButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					topButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					topButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					topButton.visible=false;
					topButton.enabled=false;
					
				}
			}
			else if (instance == bottomButton)
			{
				if(resizeEnabled)
				{
					bottomButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
					bottomButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
					bottomButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
				}
				else
				{
					bottomButton.visible=false;
					bottomButton.enabled=false;
				}
			}
			else if (instance == leftButton)
			{
				if(resizeEnabled)
				{
					leftButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					leftButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					leftButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					leftButton.visible=false;
					leftButton.enabled=false;
				}
			}
			else if (instance == rightButton)
			{
				if(resizeEnabled)
				{
					rightButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
					rightButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
					rightButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
				}
				else
				{
					rightButton.visible=false;
					rightButton.enabled=false;
				}
			}
			else if (instance == topLeftButton)
			{
				if(resizeEnabled)
				{
					topLeftButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
					topLeftButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
					topLeftButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
				}
				else
				{
					topLeftButton.visible=false;
					topLeftButton.enabled=false;
				}
			}
			else if (instance == topRightButton)
			{
				if(resizeEnabled)
				{
					topRightButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					topRightButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					topRightButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					topRightButton.visible=false;
					topRightButton.enabled=false;
				}
			}
			else if (instance == bottomLeftButton)
			{
				if(resizeEnabled)
				{
					bottomLeftButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					bottomLeftButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					bottomLeftButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					bottomLeftButton.visible=false;
					bottomLeftButton.enabled=false;
				}
			}
			else if (instance == bottomRightButton)
			{
				if(resizeEnabled)
				{
					bottomRightButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					bottomRightButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					bottomRightButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					bottomRightButton.visible=false;
					bottomRightButton.enabled=false;
				}
			}
		}
		
		override protected function partRemoved(partName:String, instance:Object):void
		{
			super.partRemoved(partName, instance);
			if (instance == closeButton)
				closeButton.removeEventListener(MouseEvent.CLICK, closeButton_clickHandler);
				
			else if (instance == minimizeButton)
				minimizeButton.removeEventListener(MouseEvent.CLICK, minimizeButton_clickHandler);
				
			else if (instance == restoreButton)
				restoreButton.removeEventListener(MouseEvent.CLICK, restoreButton_clickHandler);
				
			else if (instance == maximizeButton)
				maximizeButton.removeEventListener(MouseEvent.CLICK, maximizeButton_clickHandler);
			else if (instance == topButton)
			{
				topButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				topButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				topButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == bottomButton)
			{
				bottomButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				bottomButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				bottomButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == leftButton)
			{
				leftButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				leftButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				leftButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == rightButton)
			{
				rightButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				rightButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				rightButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == topLeftButton)
			{
				topLeftButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				topLeftButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				topLeftButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == topRightButton)
			{
				topRightButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				topRightButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				topRightButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == bottomLeftButton)
			{
				bottomLeftButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				bottomLeftButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				bottomLeftButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == bottomRightButton)
			{
				bottomRightButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				bottomRightButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				bottomRightButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
		}
		protected function minimizeButton_clickHandler(event:MouseEvent):void
		{
			dispatchEvent(new ResizeSetariaEvent(ResizeSetariaEvent.MINIMIZE));
		}
		protected function restoreButton_clickHandler(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleModule.STATE_MAXIMIZE || sizeState == SetariaTitleModule.STATE_MINIMIZE)
			{
				this.x=this.normalX;
				this.y=this.normalY;
				this.width=this.normalWidth;
				this.height=this.normalHeight;
				sizeState=SetariaTitleWindow.STATE_NORMAL;
				restoreButton.visible=false;
				restoreButton.enabled=false;
				maximizeButton.visible=true;
				maximizeButton.enabled=true;
				dispatchEvent(new ResizeSetariaEvent(ResizeSetariaEvent.RESTORE));
			}
		}
		protected function maximizeButton_clickHandler(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleWindow.STATE_NORMAL)
			{
				//				normalX=this.x;
				//				normalY=this.y;
				normalHeight=this.height;
				normalWidth=this.width;
				
				this.x=0;
				this.y=0;
				
				if(this.parent is SystemManager){
					this.height = this.parentApplication.height;
					this.width = this.parentApplication.width;
				}else{
					this.percentHeight=100;
					this.percentWidth=100;
					//					this.height=this.parent.height;
					//					this.width=this.parent.width;
				}
				//				this.percentHeight=100;
				//				this.percentWidth=100;
				
				sizeState=SetariaTitleWindow.STATE_MAXIMIZE;
				maximizeButton.visible=false;
				maximizeButton.enabled=false;
				restoreButton.visible=true;
				restoreButton.enabled=true;
				dispatchEvent(new ResizeSetariaEvent(ResizeSetariaEvent.MAXIMIZE));
			}
		}
		protected function closeButton_clickHandler(event:MouseEvent):void
		{
			dispatchEvent(new CloseEvent(CloseEvent.CLOSE));
		}
		
		/**
		 * 窗口尺寸改变时调用
		 */
		private function resize(event:Event):void
		{
			dragAmountX=parent.mouseX - dragStartMouseX;
			dragAmountY=parent.mouseY - dragStartMouseY;
			if (currentResizeHandle == topButton && parent.mouseY > 0)
			{
				this.y=Math.min(savedWindowRect.y + dragAmountY, dragMaxY);
				this.height=Math.max(savedWindowRect.height - dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == rightButton)
			{
				this.width=Math.max(savedWindowRect.width + dragAmountX, this.skin.minWidth);
			}
			else if (currentResizeHandle == bottomButton && parent.mouseY < parent.height)
			{
				this.height=Math.max(savedWindowRect.height + dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == leftButton && parent.mouseX > 0)
			{
				this.x=Math.min(savedWindowRect.x + dragAmountX, dragMaxX);
				this.width=Math.max(savedWindowRect.width - dragAmountX, this.skin.minWidth);
			}
			else if (currentResizeHandle == topLeftButton && parent.mouseX > 0 && parent.mouseY > 0)
			{
				this.x=Math.min(savedWindowRect.x + dragAmountX, dragMaxX);
				this.y=Math.min(savedWindowRect.y + dragAmountY, dragMaxY);
				this.width=Math.max(savedWindowRect.width - dragAmountX, this.skin.minWidth);
				this.height=Math.max(savedWindowRect.height - dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == topRightButton && parent.mouseX < parent.width && parent.mouseY > 0)
			{
				this.y=Math.min(savedWindowRect.y + dragAmountY, dragMaxY);
				this.width=Math.max(savedWindowRect.width + dragAmountX, this.skin.minWidth);
				this.height=Math.max(savedWindowRect.height - dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == bottomRightButton && parent.mouseX < parent.width && parent.mouseY < parent.height)
			{
				this.width=Math.max(savedWindowRect.width + dragAmountX, this.skin.minWidth);
				this.height=Math.max(savedWindowRect.height + dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == bottomLeftButton && parent.mouseX > 0 && parent.mouseY < parent.height)
			{
				this.x=Math.min(savedWindowRect.x + dragAmountX, dragMaxX);
				this.width=Math.max(savedWindowRect.width - dragAmountX, this.skin.minWidth);
				this.height=Math.max(savedWindowRect.height + dragAmountY, this.skin.minHeight);
			}
		}
		
		/**
		 * 在窗口边缘并按下鼠标左键时调用
		 */
		private function resizeButtonDown(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleWindow.STATE_NORMAL)
			{
				currentResizeHandle=event.target as Button;
				setCursor(currentResizeHandle);
				dragStartMouseX=parent.mouseX;
				dragStartMouseY=parent.mouseY;
				savedWindowRect=new Rectangle(this.x, this.y, this.width, this.height);
				dragMaxX=savedWindowRect.x + (savedWindowRect.width - this.skin.minWidth);
				dragMaxY=savedWindowRect.y + (savedWindowRect.height - this.skin.minHeight);
				systemManager.addEventListener(Event.ENTER_FRAME, resize);
				systemManager.addEventListener(MouseEvent.MOUSE_UP, resizeButtonRelease);
				systemManager.stage.addEventListener(Event.MOUSE_LEAVE, resizeButtonRelease);
			}
		}
		
		/**
		 * 在窗口边缘并弹开鼠标左键时调用
		 */
		private function resizeButtonRelease(event:MouseEvent):void
		{
			currentResizeHandle=null;
			systemManager.removeEventListener(Event.ENTER_FRAME, resize);
			systemManager.removeEventListener(MouseEvent.MOUSE_UP, resizeButtonRelease);
			systemManager.stage.removeEventListener(Event.MOUSE_LEAVE, resizeButtonRelease);
			CursorManager.removeAllCursors();
		}
		
		/**
		 * 在窗口边缘并鼠标离开时调用
		 */
		private function resizeButtonRollOut(event:MouseEvent):void
		{
			if (!event.buttonDown)
				CursorManager.removeAllCursors();
		}
		
		/**
		 * 在窗口边缘并鼠标进入时调用
		 */
		private function resizeButtonRollOver(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleWindow.STATE_NORMAL)
			{
				if (!event.buttonDown)
				{
					setCursor(event.target as Button);
				}
			}
		}
		
		/**
		 * 鼠标经过窗口边缘时设置鼠标显示形状
		 */
		private function setCursor(target:Button):void
		{
			switch (target)
			{
				case topButton:
				case bottomButton:
					CursorManager.setCursor(DEFAULT_RESIZE_CURSOR_VERTICAL, 2, -10, -10);
					break;
				case rightButton:
				case leftButton:
					CursorManager.setCursor(DEFAULT_RESIZE_CURSOR_HORIZONTAL, 2, -10, -10);
					break;
				case topLeftButton:
				case bottomRightButton:
					CursorManager.setCursor(DEFAULT_RESIZE_CURSOR_TL_BR, 2, -10, -10);
					break;
				case topRightButton:
				case bottomLeftButton:
					CursorManager.setCursor(DEFAULT_RESIZE_CURSOR_TR_BL, 2, -10, -10);
					break;
			}
		}
		
		/**
		 * 在窗口标题双击时调用
		 */
		private function titleDoubleClick(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleModule.STATE_NORMAL)
			{
				maximizeButton_clickHandler(event);
			}
			else
			{
				restoreButton_clickHandler(event);
			}
		}
		
		/**
		 * 按住窗口标题开始移动时调用
		 */
		private function dragStart(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleModule.STATE_NORMAL && !(event.target is Button))
			{
				this.startDrag(false, new Rectangle(0, 0, parent.width - this.width, parent.height - this.height));
				systemManager.addEventListener(MouseEvent.MOUSE_UP, dragStop);
				systemManager.stage.addEventListener(Event.MOUSE_LEAVE, dragStop);
			}
		}
		
		/**
		 * 按住窗口标题停止移动时调用
		 */
		private function dragStop(event:Event):void
		{
			this.stopDrag();
			systemManager.removeEventListener(MouseEvent.MOUSE_UP, dragStop);
			systemManager.stage.removeEventListener(Event.MOUSE_LEAVE, dragStop);
			if(!(event.target is Button)){
				this.normalX = this.x;
				this.normalY = this.y;
			}
		}
		
		public function get showTitleGroup():Boolean{
			return this._showTitle;
		}
		public function set showTitleGroup(flag:Boolean):void{
			this._showTitle = flag;
			//			if(flag){
			//				this.titleGroup.visible = true;
			//				this.titleGroup.includeInLayout = true;
			//			}else{
			//				this.titleGroup.visible = false;
			//				this.titleGroup.includeInLayout = false;
			//			}
		}
		public function get showMaximizButton():Boolean{
			return this._maximizable;
		}
		public function set showMaximizButton(flag:Boolean):void{
			this._maximizable = flag;
		}
		public function get showMinimizButton():Boolean{
			return this._minimizable;
		}
		public function set showMinimizButton(flag:Boolean):void{
			this._minimizable = flag;
		}
		public function get resizeEnabled():Boolean{
			return this._resizable;
		}
		public function set resizeEnabled(flag:Boolean):void{
			this._resizable = flag;
		}
		public function get showCloseButton():Boolean{
			return this._close;
		}
		public function set showCloseButton(flag:Boolean):void{
			this._close = flag;
		}
		public function get dragable():Boolean
		{
			return _dragable;
		}
		
		public function set dragable(value:Boolean):void
		{
			_dragable = value;
		}
		
	}
}